﻿//-----------------------------------------------------------------------
// <copyright file="SR.cs" company="CodePlex">
//     Copyright (c) Doug Holland, CodePlex. All rights reserved.
// </copyright>
//-----------------------------------------------------------------------
namespace CodePlex.Diagnostics.Silverlight
{
    using System;
    using System.Globalization;
    using System.Resources;
    using System.Threading;

    /// <summary>
    /// Provides string resources within the CodePlex.Diagnostics framework.
    /// </summary>
    internal sealed class SR
    {
        #region SR Internal Members

        /// <summary>
        /// Exception message for the <see cref="T:CodePlex.Diagnostics.PublishedException"/>.
        /// </summary>
        internal const string PublishedException = "PublishedException";

        /// <summary>
        /// The publication identifier.
        /// </summary>
        internal const string PublicationId = "PublicationId";

        /// <summary>
        /// Exception message for the <see cref="T:System.InvalidOperationException"/> thrown when attempting to update process exit details for a process that is still alive. 
        /// </summary>
        internal const string ProcessAlive = "ProcessAlive";

        /// <summary>
        /// Exception message for the <see cref="T:CodePlex.Diagnostics.UnhandledException"/> class which is now obsolete although remains for backwards compatibility. 
        /// </summary>
        internal const string UnhandledException = "UnhandledException";

        #endregion

        #region SR Private Fields

        /// <summary>
        /// Thread synchronization object.
        /// </summary>
        private static object internalSyncObject;

        /// <summary>
        /// Singleton instance of the <see cref="T:SR"/> class.
        /// </summary>
        private static SR instance;

        /// <summary>
        /// <see cref="T:System.Resources.ResourceManager"/> instance enabling run-time access to resources.
        /// </summary>
        private ResourceManager resources;

        #endregion

        #region private SR()

        /// <summary>
        /// Prevents a default instance of the <see cref="T:SR"/> class from being created.
        /// </summary>
        private SR()
        {
            // create an instance of the ResourceManager class using the base name for the resources within the CodePlex.Diagnostics project.
            this.resources = new ResourceManager("CodePlex.Diagnostics.Silverlight.CodePlex.Diagnostics.Silverlight", this.GetType().Assembly);
        }

        #endregion

        #region public static CultureInfo Culture

        /// <summary>
        /// Gets the <see cref="T:System.Globalization.CultureInfo"/> instance for which strings should be localized.
        /// </summary>
        /// <value>Returns the <see cref="M:System.Threading.Thread.CurrentUICulture"/>.</value>
        public static CultureInfo Culture
        {
            get
            {
                return Thread.CurrentThread.CurrentUICulture;
            }
        }

        #endregion

        #region public ResourceManager ResourceManager

        /// <summary>
        /// Gets the <see cref="T:System.Resources.ResourceManager"/> instance.
        /// </summary>
        public ResourceManager ResourceManager
        {
            get
            {
                return this.resources;
            }
        }

        #endregion

        #region private static object InternalSyncObject

        /// <summary>
        /// Gets the internal sync object.
        /// </summary>
        /// <value>The internal sync object.</value>
        private static object InternalSyncObject
        {
            get
            {
                if (SR.internalSyncObject == null)
                {
                    object obj = new object();

                    Interlocked.CompareExchange(ref SR.internalSyncObject, obj, null);
                }

                return SR.internalSyncObject;
            }
        }

        #endregion

        #region public static string GetString(string name)

        /// <summary>
        /// Gets the value of the <see cref="T:System.String"/> resource localized for the <see cref="M:System.Threading.Thread.CurrentUICulture"/>.
        /// </summary>
        /// <param name="name">The name of the <see cref="T:System.String"/> resource.</param>
        /// <returns>The value of the <see cref="T:System.String"/> resource localized for the <see cref="M:System.Threading.Thread.CurrentUICulture"/>.</returns>
        public static string GetString(string name)
        {
            SR sr = SR.GetInstance();

            if (sr == null)
            {
                return null;
            }

            return sr.ResourceManager.GetString(name, SR.Culture);
        }

        #endregion

        #region private static SR GetInstance()

        /// <summary>
        /// Gets an instance of the <see cref="T:CodePlex.Diagnostics.SR"/> class.
        /// </summary>
        /// <returns>An instance of the <see cref="T:CodePlex.Diagnostics.SR"/> class.</returns>
        private static SR GetInstance()
        {
            if (SR.instance == null)
            {
                lock (SR.InternalSyncObject)
                {
                    // use the double-check locking pattern.
                    if (SR.instance == null)
                    {
                        SR.instance = new SR();
                    }
                }
            }

            return SR.instance;
        }

        #endregion
    }
}
